/*
 * UART0
 * TX GPIOD18 AD19 function1
 * RX GPIOD14 AE19 function1
 */

#include "../gpio.h"
#include "../PLL/pll.h"
#include "../MATH/my_math.h"
#include "../VIC/vic_reg.h"
#include "../PUBLIC/public.h"
#include "uart.h"

char buff[10];
int t = 0;          // 接收长度
int over_flag = 0;  // 1表示输入完成

void uart0_init(int baud){
    int p, m, s, tmp;
    float tmpf;

    GPIODALTFN0 &= ~((3 << 28));
    GPIODALTFN1 &= ~((3 << 4));
    GPIODOUTENB &= ~((1 << 18) | (1 << 14));

    GPIODALTFN0 |= ((1 << 28));
    GPIODALTFN1 |= ((1 << 4));
    GPIODOUTENB |= ((1 << 18));

    // 设置UART0时钟，一般设置为10MHz
    UARTCLKENB_UART0 |= (1 << 2);
    UARTCLKGEN0L_UART0 &= ~((7 << 2) | (0xFF << 5));
    p = (PLLSETREG0 >> 18) & 0x3F;
    m = (PLLSETREG0 >> 8) & 0x3FF;
    s = (PLLSETREG0 >> 0) & 0xFF;
    tmp = (m * 24) / (p * my_pow(2, s));    // PLL0的时钟值
    UARTCLKGEN0L_UART0 |= ((tmp / 10 - 1) << 5);  // 选择PLL[0],生成10MHz时钟
    // UARTCLKGEN0L |= ((55 - 1) << 5);     // 生成10MHz时钟
    // UARTCLKGEN0L |= ((200 - 1) << 5);

    // 配置波特率 115200
    // UARTIBRD &= ~0xFFFF;
    // UARTIBRD |= 5;
    // UARTFBRD &= ~0x3F;
    // UARTFBRD |= 27;

    // 配置波特率
    UARTIBRD &= ~0xFFFF;
    tmpf = (10000000 / (16.0 * baud));
    UARTIBRD |= (int)tmpf;      // 整数部分
    UARTFBRD &= ~0x3F;
    tmpf = tmpf - (int)tmpf;    // 小数部分
    UARTFBRD |= (int)(tmpf * 2 * 32 + 0.5);

    // 8N1
    UARTLCR_H &= ~((3 << 5) | (0x1F << 0));
    UARTLCR_H |= ((3 << 5));

    // 配置中断
    UARTIMSC |= (1 << 4);

    // VICINTENCLEAR_CH0 = (1 << 7);
    // VICINTSELECT_CH0 &= ~(1 << 7);     // IRQ
    // VICVECTADDR_UART0 = (u32)uart0_ISR;
    // VICINTENABLE_CH0 = (1 << 7);
    vic_init(7, (u32)uart0_ISR);

    // UART TX RX使能
    UARTCR |= ((1 << 0) | (1 << 8) | (1 << 9));
}

char my_getc(){

    // if((UARTFR >> 6) & 1){
    //     rec = UARTDR & 0xFF;
    // }
    while((UARTFR & (1 << 6)) == 0);
    return UARTDR;
}

void my_putc(char c){
    while(UARTFR & (1 << 3));
    UARTDR = c;
}

void my_puts(char *p){
    int i = 0;

    while(p[++i] != 0){
        my_putc(p[i]);
    }
}

int get_uint(){
    t = 0;

    return hex2dec(buff);
}

void uart0_ISR(){
    char ch;

    ch = UARTDR;
    
    my_putc(ch);    // 回显

    if(ch == ' '){
        over_flag = 1;
    }

    if(ch == '\r'){
        over_flag = 1;
        my_putc('\n');
    }

    if(ch == '\b'){
        my_putc(' ');
        my_putc('\b');
        over_flag = 2;
    }

    if(over_flag == 1){
        buff[t] = '\0';
    }else if(over_flag == 2){
        t--;
        over_flag = 0;
    }else{
        buff[t++] = ch;
    }
    

    VICADDRESS_CH0 = 0X0;
}

